#ifndef IO_FILE_H_INCLUDED
#define IO_FILE_H_INCLUDED

#include "config.hpp"

#include <string>

namespace commons { namespace io {

	namespace detail { 
		class source_file_impl; 
		class sink_file_impl;
	}

	//DECLARE_OPEN_VARS(open_mode)

//	template <class char_type> class basic_sink_file;
//	template <class char_type> class basic_source_file;

	template <class char_type>
	class basic_sink_file  {
	public :
		
		DECLARE_SINK_OPEN_VARS(open_mode)
		typedef char_type char_t;

		basic_sink_file ();
		explicit basic_sink_file (std::basic_string<char_type> const & name, open_mode mode = binary | append);
		~basic_sink_file ();

		bool open(std::basic_string<char_type> const & name, open_mode mode = binary | append);
		inline bool is_open() const { return impl == NULL ? false : true; }
		void close();
		std::streamsize write(char const * buf, std::streamsize n);
		offset_type seek(offset_type where);
		offset_type seek(seek_dir way);

	private :

		basic_sink_file (basic_sink_file const &);
		basic_sink_file & operator=(basic_sink_file const &);

		detail::sink_file_impl * impl_;
	};

	template <class char_type>
	class basic_source_file {
	public :
		
		DECLARE_SOURCE_OPEN_VARS(open_mode)
		typedef char_type char_t;

		basic_source_file();
		explicit basic_source_file(std::basic_string<char_type> const & name, open_mode mode = binary);
		~basic_source_file();

		bool open(std::basic_string<char_type> const & name, open_mode mode = binary);
		inline bool is_open() const { return impl == NULL ? false : true; }
		void close();
		std::streamsize read(char * buf, std::streamsize n);
		offset_type seek(offset_type where);
		offset_type seek(seek_dir way);

	private :

		basic_source_file(basic_source_file const &);
		basic_source_file& operator=(basic_source_file const &);

		detail::source_file_impl * impl_;
	};

	typedef basic_sink_file<char> sink_file;
	typedef basic_sink_file<wchar_t> wsink_file;
	typedef basic_source_file<char> source_file;
	typedef basic_source_file<wchar_t> wsource_file;

} }

#endif
